#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QPushButton>
#include <QLineEdit>
#include <QGridLayout>
#include <QMessageBox>
#include <QFileDialog>
#include <QTextStream>
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);

    QPushButton* button   = new QPushButton(this);
    QLineEdit*   lineEdit = new QLineEdit(this);

    // 新建栅格布局管理器
    QGridLayout* gridLayout = new QGridLayout();
    // 添加部件，从第0行0列开始，占据1行1列
    gridLayout->addWidget(button, 0, 0, 1, 1);
    // 添加部件，从第0行1列开始，占据1行2列
    gridLayout->addWidget(lineEdit, 0, 1, 1, 2);
    // 添加部件，从第1行0列开始，占据1行3列
    gridLayout->addWidget(ui->textEdit, 1, 0, 1, 3);
    ui->centralWidget->setLayout(gridLayout);

    // 初始化窗口标题为文件名
    setWindowTitle(curFile);

    findDialog->setWindowTitle(tr("查找"));
    QPushButton* findButton = new QPushButton(tr("查找下一个"), findDialog);
    QVBoxLayout* boxLayout  = new QVBoxLayout(findDialog);
    boxLayout->addWidget(findLineEdit);
    boxLayout->addWidget(findButton);
    connect(findButton, &QPushButton::clicked, this, &MainWindow::showFindText);

    // 状态栏显示临时消息
    // ui->statusBar->showMessage(tr("这我学习Qt的一个程序"), 2000);

    statusLabel->setMinimumSize(150, 20);            // 设置标签最小大小
    statusLabel->setFrameShape(QFrame::StyledPanel); // 设置标签形状
    statusLabel->setFrameShadow(QFrame::Sunken);     // 设置标签阴影
    ui->statusBar->addWidget(statusLabel);
    statusLabel->setText(tr("这是我学习Qt的一个程序"));

    permanent->setFrameStyle(QFrame::Box | QFrame::Sunken);
    permanent->setText(tr("<a href=\"http://www.qter.org\">qter.org</a>"));
    permanent->setTextFormat(Qt::RichText);
    permanent->setOpenExternalLinks(true);
    ui->statusBar->addPermanentWidget(permanent);
}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::newFile() {
    if (maybeSave()) {
        isUntitled = true;
        curFile    = tr("未命名.txt");
        setWindowTitle(curFile);
        ui->textEdit->clear();
        ui->textEdit->setVisible(true);
    }
}

bool MainWindow::maybeSave() {
    // 如果文档被更改了
    if (ui->textEdit->document()->isModified()) {
        // 自定义一个警告对话框
        QMessageBox box;
        box.setWindowTitle(tr("警告"));
        box.setIcon(QMessageBox::Warning);
        box.setText(curFile + tr(" 尚未保存，是否保存？"));
        QPushButton* yesButton =
            box.addButton(tr("是(&Y)"), QMessageBox::YesRole);
        box.addButton(tr("否(&N)"), QMessageBox::NoRole);
        QPushButton* cancelButton =
            box.addButton(tr("取消"), QMessageBox::RejectRole);
        box.exec();
        if (box.clickedButton() == yesButton) {
            return save();
        } else if (box.clickedButton() == cancelButton) {
            return false;
        }
    }
    // 如果文档没有被更改，则直接返回true
    return true;
}

bool MainWindow::save() {
    if (isUntitled) {
        return saveAs();
    } else {
        return saveFile(curFile);
    }
}

bool MainWindow::saveAs() {
    QString fileName =
        QFileDialog::getSaveFileName(this, tr("另存为"), curFile);
    if (fileName.isEmpty()) {
        return false;
    }
    return saveFile(fileName);
}

bool MainWindow::saveFile(const QString& fileName) {
    QFile file(fileName);

    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        // %1和%2分别对应后面arg两个参数, \n起换行的作用
        QMessageBox::warning(
            this, tr("多文档编辑器"),
            tr("无法写入文件 %1, \n %2").arg(fileName).arg(file.errorString()));
        return false;
    }

    QTextStream out(&file);
    // 鼠标指针变为等待状态
    QApplication::setOverrideCursor(Qt::WaitCursor);
    out << ui->textEdit->toPlainText();
    // 鼠标指针恢复原来的状态
    QApplication::restoreOverrideCursor();
    isUntitled = false;
    // 获得文件的标准路径
    curFile = QFileInfo(fileName).canonicalFilePath();
    setWindowTitle(curFile);
    return true;
}

bool MainWindow::loadFile(const QString& fileName) {
    QFile file(fileName); // 新建QFile对象
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        QMessageBox::warning(
            this, tr("多文档编辑器"),
            tr("无法读取文件 %1:\n%2.").arg(fileName).arg(file.errorString()));
        return false; // 只读方式打开文件，出错则提示，并返回false
    }
    QTextStream in(&file); // 新建文本流对象
    QApplication::setOverrideCursor(Qt::WaitCursor);
    // 读取文件的全部文本内容，并添加到编辑器中
    ui->textEdit->setPlainText(in.readAll());
    QApplication::restoreOverrideCursor();

    // 设置当前文件
    curFile = QFileInfo(fileName).canonicalFilePath();
    setWindowTitle(curFile);
    return false;
}

void MainWindow::closeEvent(QCloseEvent* event) {
    // 如果maybeSave()函数返回true，则关闭程序，
    // 否则忽略该事件
    if (maybeSave()) {
        event->accept();
    } else {
        event->ignore();
    }
}

void MainWindow::on_actionNew_triggered() {
    newFile();
}

void MainWindow::on_actionSave_triggered() {
    save();
}

void MainWindow::on_actionSaveAs_triggered() {
    saveAs();
}

void MainWindow::on_actionOpen_triggered() {
    if (maybeSave()) {
        QString fileName = QFileDialog::getOpenFileName(this);
        // 如果文件名不为空，则加载文件
        if (!fileName.isEmpty()) {
            loadFile(fileName);
            ui->textEdit->setVisible(true);
        }
    }
}

void MainWindow::on_actionClose_triggered() {
    if (maybeSave()) {
        ui->textEdit->setVisible(false);
    }
}

void MainWindow::on_actionExit_triggered() {
    // 先执行关闭操作，再退出程序
    // aApp是指向应用程序的全局指针
    on_actionClose_triggered();
    qApp->quit();
}

void MainWindow::on_actionUndo_triggered() {
    ui->textEdit->undo();
}

void MainWindow::on_actionCut_triggered() {
    ui->textEdit->cut();
}

void MainWindow::on_actionCopy_triggered() {
    ui->textEdit->copy();
}

void MainWindow::on_actionPaste_triggered() {
    ui->textEdit->paste();
}

void MainWindow::showFindText() {
    QString str = findLineEdit->text();
    if (!ui->textEdit->find(str, QTextDocument::FindBackward)) {
        QMessageBox::warning(this, tr("查找"), tr("找不到%1").arg(str));
    }
}

void MainWindow::on_actionFind_triggered() {
    findDialog->show();
}
